<template>
  <div><br/>
    操作步骤：<br/>
    1、点击“选择文件”，选择要上传的文件<br/>
    2、点击“开始上传”，开始上传文件<br/>
    3、如需重新上传请重复上边的步骤。<br/>
    4、只能删除空文件夹。<br/>
    5、当前选择的上传位置是空 说明是新建一个 根目录。<br/>
    <div class="demo-block demo-zh-CN">
      当前选择的上传位置是==>{{checkNode}}
      <el-link v-if="this.checkNode !== ''" type="primary" @click="clearCheckNode">清空</el-link>
      <div class="source">
        <el-input
          placeholder="输入关键字进行过滤"
          v-model="filterText">
        </el-input>
        <el-input v-model="nodeNameForRootNode" placeholder="输入后回车创建根节点"
                  @keyup.enter.native="createNodeNameForRootNode"></el-input>


        <el-tree
          class="filter-tree"
          :data="data"
          :highlight-current="true"
          accordion
          node-key="id"
          @node-click="handleNodeClick"
          :filter-node-method="filterNode"
          :render-content="renderContent"
          ref="tree">
        </el-tree>
      </div>
    </div>
    <div id="uploader" class="wu-example">
      <div class="btns" style="float:left;padding-right: 20px">
        <div id="picker">选择文件</div>
      </div>
      <div id="ctlBtn" class="webuploader-pick" @click="upload()">开始上传</div>

    </div>
    <!--用来存放文件信息-->
    <div id="thelist" class="uploader-list">
      <div v-if="uploadFile.id" :id='uploadFile.id'><span>{{uploadFile.name}} {{percentageMessage}}</span>&nbsp;
        <el-tooltip class="item" effect="dark" :content="uploadFile.name" placement="top-start">
          文件名
          <el-progress class="progressBar" :text-inside="true" :stroke-width="26"
                       :percentage="percentage"></el-progress>
        </el-tooltip>
      </div>
    </div>
  </div>
</template>
<script>
  import $ from '../../../../static/plugins/jquery/dist/jquery.js'
  import webuploader from '../../../../static/plugins/webuploader/dist/webuploader.js'
  import '../../../../static/css/webuploader/webuploader.css'
  import * as mediaApi from '../api/media'

  export default {
    data() {
      return {
        uploader: {},
        uploadFile: {},
        // 进度
        percentage: 0,
        // 上传文件分片的时候的提示信息
        percentageMessage: '',
        fileMd5: '',
        // 输入框
        filterText: '',
        // 上传文件选中的节点
        checkNode: '',
        // 创建文件夹选中的节点
        createNode: '',
        // 创建根节点下的文件夹
        nodeNameForRootNode: '',
        // 节点
        data: [{
          label: '一级 1',
          children: [{
            label: '二级 1-1',
            children: [{
              label: '三级 1-1-1'
            }]
          }]
        }, {
          label: '一级 2',
          children: [{
            label: '二级 2-1',
            children: [{
              label: '三级 2-1-1'
            }]
          }, {
            label: '二级 2-2',
            children: [{
              label: '三级 2-2-1'
            }]
          }]
        }, {
          label: '一级 3',
          children: [{
            label: '二级 3-1',
            children: [{
              label: '三级 3-1-1'
            }]
          }, {
            label: '二级 3-2',
            children: [{
              label: '三级 3-2-1'
            }]
          }]
        }]
      }
    },
    watch: {
      filterText(val) {
        this.$refs.tree.filter(val);
      },
      // 记录进度条的信息
      percentage(val) {
        this.percentageMessage='上传中'
        if (val === 100) {
          // 添加进进度条百分百状态
          document.getElementsByClassName("progressBar")[0].classList.add("is-success")
          this.percentageMessage='上传完成'
        }
      }
    },
    methods: {
      // 过滤节点
      filterNode(value, data) {
        if (!value) return true;
        return data.label.indexOf(value) !== -1;
      },
      // 单选节点
      handleNodeClick(data, node, c) {
        //单击节点的时候要确定当前选择的路径
        this.checkNode = this.reverseTraversalOfNodes(node)
      },
      //清空当前节点
      clearCheckNode() {
        this.checkNode = ''
      },
      // 逆向遍历节点
      reverseTraversalOfNodes(node) {
        let path = ""
        if (node.parent !== null) {
          path += this.reverseTraversalOfNodes(node.parent)
          path = path + "/" + node.data.id
        }
        return path
      },
      // 节点内的删除和新增
      renderContent(h, {node, data, store}) {
        return (
          <span class="custom-tree-node">
            <span>{node.label}</span>
            <span>
              <el-button size="mini" type="text" on-click={e => {
                // 注意这个添加和点击node搜索有冒泡
                e.stopPropagation();
                this.append(node, data)
              }}>添加文件夹</el-button>
              <el-button size="mini" type="text" on-click={e => {
                e.stopPropagation();
                this.remove(node, data)
              }}>删除文件夹</el-button>
            </span>
          </span>);
      },
      append(node, data) {
        this.createNode = this.reverseTraversalOfNodes(node);
        this.$prompt('请输入文件夹名称', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
        }).then(({value}) => {
          let folderMappingRequest = {
            folderPath: this.createNode,
            folderName: value
          }
          mediaApi.folderAdd(folderMappingRequest).then(response => {
            if (response.success) {
              this.$message.success('添加文件夹成功');
              this.checkNode = ''
              mediaApi.folderMapping().then(response => {
                this.data = response.children;
              })
            } else {
              this.$message.error('添加失败');
            }
          })
        }).catch(() => {

        });
      },
      remove(node, data) {
        this.$confirm('此操作将永久删除该文件夹, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.handleNodeClick(null, node, null);
          let folderMappingRequest = {
            folderPath: this.checkNode,
            folderName: node.data.id
          }
          mediaApi.folderDel(folderMappingRequest).then(response => {
            if (response.success) {
              this.$message.success('删除文件夹成功');
              this.checkNode = ''
              mediaApi.folderMapping().then(response => {
                this.data = response.children;
              })
            } else {
              this.$message.error('删除失败,文件夹有内容,请先再视频管理中删除该文件夹下视频');
            }
          })
        }).catch((error) => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        });
      },
      // 创建根节点
      createNodeNameForRootNode() {
        let folderMappingRequest = {
          folderPath: '',
          folderName: this.nodeNameForRootNode
        }
        console.log(folderMappingRequest);
        mediaApi.folderAdd(folderMappingRequest).then(response => {
          if (response.success) {
            this.$message.success('添加文件夹成功');
            this.checkNode = ''
            mediaApi.folderMapping().then(response => {
              this.data = response.children;
            })
          } else {
            this.$message.error('添加失败');
          }
        })
      },
      //开始上传
      upload() {
        if (this.uploadFile && this.uploadFile.id) {
          if (this.checkNode == null || this.checkNode === '') {
            this.$message.error('请选择上传路径');
            document.getElementsByClassName("filter-tree")[0].style.border = 'solid 1px red';
            setInterval(function () {
              document.getElementsByClassName("filter-tree")[0].style.border = 'solid 1px transparent';
            }, 3000)
            return false;
          }
          this.percentageMessage='分片中'
          this.uploader.upload(this.uploadFile.id);
        } else {
          this.$message.error('请选择上传文件');
        }
      }
    },
    mounted() {
      const staticThis = this;
      // 获取文件夹映射
      mediaApi.folderMapping().then(response => {
        this.data = response.children;
      })

//      var fileMd5;
//      var uploadFile;
      WebUploader.Uploader.register({
          "before-send-file": "beforeSendFile",
          "before-send": "beforeSend",
          "after-send-file": "afterSendFile"
        }, {
          beforeSendFile: function (file) {
            // 创建一个deffered,用于通知是否完成操作
            var deferred = WebUploader.Deferred();
            // 计算文件的唯一标识，用于断点续传  这里传file就行
            (new WebUploader.Uploader()).md5File(file)
              .then(function (val) {
                this.fileMd5 = val;
                this.uploadFile = file;
                //向服务端请求注册上传文件
                $.ajax(
                  {
                    type: "POST",
                    url: "/api/media/upload/register",
                    data: {
                      // 文件唯一表示
                      path: this.checkNode,
                      fileMd5: this.fileMd5,
                      fileName: file.name,
                      fileSize: file.size,
                      mimetype: file.type,
                      fileExt: file.ext
                    },
                    dataType: "json",
                    success: function (response) {
                      if (response.success) {
                        this.percentageMessage='上传中'
                        deferred.resolve();
                      } else {
                        deferred.reject();
                      }
                    }
                  }
                );
              }.bind(this));
            return deferred.promise();
          }.bind(this),
          beforeSend: function (block) {
            var deferred = WebUploader.Deferred();
            // 每次上传分块前校验分块，如果已存在分块则不再上传，达到断点续传的目的
            $.ajax(
              {
                type: "POST",
                url: "/api/media/upload/checkchunk",
                data: {
                  path: this.checkNode,
                  // 文件唯一表示
                  fileMd5: this.fileMd5,
                  // 当前分块下标
                  chunk: block.chunk,
                  // 当前分块大小
                  chunkSize: block.end - block.start
                },
                dataType: "json",
                success: function (response) {
                  if (response.fileExist) {
                    // 分块存在，跳过该分块
                    deferred.reject();
                  } else {
                    // 分块不存在或不完整，重新发送
                    deferred.resolve();
                  }
                }
              }
            );
            //构建fileMd5参数，上传分块时带上fileMd5
            this.uploader.options.formData.fileMd5 = this.fileMd5;
            this.uploader.options.formData.chunk = block.chunk;
            this.uploader.options.formData.path = this.checkNode;
            return deferred.promise();
          }.bind(this),
          afterSendFile: function (file) {
            // 合并分块
            console.log("发送合并分块请求")
            $.ajax(
              {
                type: "POST",
                url: "/api/media/upload/mergechunks",
                data: {
                  path: this.checkNode,
                  fileMd5: this.fileMd5,
                  fileName: file.name,
                  fileSize: file.size,
                  mimetype: file.type,
                  fileExt: file.ext
                },
                success: function (response) {
                  console.log("获取合并结果")
                  //在这里解析合并成功结果
                  if (response && response.success) {
                    staticThis.$message({
                      showClose: true,
                      message: '上传成功',
                      type: 'success'
                    });
                    console.log("合并分块成功")
                  } else {
                    staticThis.$message({
                      showClose: true,
                      message: '上传失败',
                      type: 'error'
                    });
                    console.log("合并分块失败")
                  }
                }
              }
            );
          }.bind(this)
        }
      );
      // 创建uploader对象，配置参数
      this.uploader = WebUploader.create(
        {
          swf: "/static/plugins/webuploader/dist/Uploader.swf",//上传文件的flash文件，浏览器不支持h5时启动flash
          server: "/api/media/upload/uploadchunk",//上传分块的服务端地址，注意跨域问题
          fileVal: "file",//文件上传域的name
          pick: "#picker",//指定选择文件的按钮容器
          auto: false,//手动触发上传
          disableGlobalDnd: true,//禁掉整个页面的拖拽功能
          chunked: true,// 是否分块上传
          chunkSize: 1024 * 1024 * 5, // 分块大小（默认5M）
          threads: 20, // 开启多个线程（默认3个）
          prepareNextFile: true// 允许在文件传输时提前把下一个文件准备好
        }
      );

      // 将文件添加到队列
      this.uploader.on("fileQueued", function (file) {
          this.uploadFile = file;
          this.percentage = 0;

        }.bind(this)
      );
      //选择文件后触发
      this.uploader.on("beforeFileQueued", function (file) {
//     this.uploader.removeFile(file)
        //重置uploader
        this.uploader.reset()
        this.percentage = 0;
      }.bind(this));

      // 监控上传进度
      // percentage:代表上传文件的百分比
      this.uploader.on("uploadProgress", function (file, percentage) {
        this.percentage = Math.ceil(percentage * 100);
      }.bind(this));
      //上传失败触发
      this.uploader.on("uploadError", function (file, reason) {
        staticThis.$message({
          showClose: true,
          message: '上传失败 ',
          type: 'error'
        });
      });
      //上传成功触发
      this.uploader.on("uploadSuccess", function (file, response) {
        staticThis.$message({
          showClose: true,
          message: '服务器合并文件中',
          type: 'warning'
        });
      });
      //每个分块上传请求后触发
      this.uploader.on('uploadAccept', function (file, response) {
        if (!(response && response.success)) {//分块上传失败，返回false
          return false;
        }
      });

    }
  }

</script>
<style scoped>
  .demo-block {
    border: 1px solid #ebebeb;
    border-radius: 3px;
    transition: .2s;
    width: 40%;
  }

  .source {
    padding: 24px;
  }

  .filter-tree {
    font-size: 14px;
  }

  .filter-tree {
    border: solid 1px transparent;
  }

  .progressBar {
    width: 40%;
  }
</style>
